/*
 * point.hpp
 *
 *  Created on: 16/11/2011
 *      Author: Aeradon
 */

#ifndef POINT_HPP_
#define POINT_HPP_

template <typename T>
class Point
{
public:
	Point(T x, T y) :
			x(x),
			y(y)
	{	}

	Point() :
			x(0),
			y(0)
	{	}

	Point(const Point& other) :
			x(other.x),
			y(other.y)
	{	}

	virtual ~Point()
	{	}

	void setXY(T x, T y)
	{
		this->x = x;
		this->y = y;
	}

	Point& operator=(const Point &rhs)
	{
		x = rhs.x;
		y = rhs.y;
	    return *this;
	}

	Point& operator+=(const Point &rhs)
	{
		this->x += rhs.x;
		this->y += rhs.y;
		return *this;
	}

	Point operator+(const Point &rhs)
	{
		return Point(this->x + rhs.x, this->y + rhs.y);
	}
	Point operator+(const T & scalar)
	{
		return Point(this->x + scalar, this->y + scalar);
	}

	Point& operator-=(const Point &rhs)
	{
		this->x -= rhs.x;
		this->y -= rhs.y;
		return *this;
	}

	Point operator-(const Point &rhs)
	{
		return Point(this->x - rhs.x, this->y - rhs.y);
	}
	Point operator-(const T & scalar)
	{
		return Point(this->x - scalar, this->y - scalar);
	}

	Point operator*(const Point & rhs)
	{
		return Point(this->x * rhs.x, this->y * rhs.y);
	}

	Point operator*(const T & scalar)
	{
		return Point(this->x * scalar, this->y * scalar);
	}

	Point& operator*=(const T & scalar)
	{
		this->x *= scalar;
		this->y *= scalar;
		return *this;
	}

	Point operator/(const T & scalar)
	{
		return Point(this->x / scalar, this->y / scalar);
	}

	Point operator/(const Point &rhs)
	{
		return Point(this->x / rhs.x, this->y / rhs.y);
	}

	Point& operator/=(const Point &rhs)
	{
		this->x /= rhs.x;
		this->y /= rhs.y;
		return *this;
	}

	bool operator==(const Point &rhs) const
	{
		return (this->x == rhs.x && this->y == rhs.y);
	}

	bool operator!=(const Point &rhs) const
	{
		return (this->x != rhs.x || this->y != rhs.y);
	}

	bool operator<(const Point &rhs) const
	{
		return (this->x == rhs.x ? this->y < rhs.y : this->x < rhs.x);
	}

	bool operator>(const Point &rhs) const
	{
		return (this->x == rhs.x ? this->y > rhs.y : this->x > rhs.x);
	}

	template <typename T2>
	operator Point<T2>()
	{
		return(Point<T2>((T2)this->x,(T2)this->y));
	}

public:
	T x,y;
};

#endif /* POINT_HPP_ */
